// dh-inventory 云对象 - 内部库存管理
const db = uniCloud.database();
const _ = db.command;
const { autoMountHospitalId, softDelete, batchSoftDelete } = require('dh-common');

/**
 * 统一响应格式化辅助函数
 */
function formatResponse(code, data = null, message = 'success', extraFields = {}) {
	return {
		code,
		data,
		message,
		success: (code === 200 || code === 201),
		timestamp: Date.now(),
		...extraFields
	};
}

/**
 * 统一错误响应辅助函数
 */
function formatError(error, defaultMessage = '操作失败') {
	console.error('[dh-inventory] 错误:', error);
	return {
		code: 500,
		message: error.message || defaultMessage,
		success: false,
		timestamp: Date.now()
	};
}

module.exports = {
	/**
	 * 请求前拦截
	 */
	async _before(methodName, params) {
		const uniIdToken = this.getUniIdToken();
		console.log(`[dh-inventory] 调用方法: ${methodName}, 用户ID: ${uniIdToken?.uid}`);

		// 写操作需要权限验证
		const writeMethods = ['create', 'update', 'delete', 'batch', 'adjust', 'scan'];
		if (methodName && writeMethods.some(method => methodName.toLowerCase().includes(method))) {
			if (!uniIdToken || !uniIdToken.uid) {
				throw new Error('401|未授权的访问');
			}
		}

		// 参数清理
		if (params && typeof params === 'object') {
			for (let key in params) {
				if (typeof params[key] === 'string') {
					params[key] = params[key].trim();
				}
			}
		}
	},

	/**
	 * 根据ID获取库存物品
	 */
	async getInventoryById(id) {
		try {
			if (!id) {
				return formatResponse(400, null, '库存ID不能为空');
			}

			const res = await db.collection('dh-inventory').doc(id).get();
			if (res.data.length === 0) {
				return formatResponse(404, null, '库存物品不存在');
			}
			return formatResponse(200, res.data[0]);
		} catch (error) {
			return formatError(error, '获取库存物品失败');
		}
	},

	/**
	 * 根据物品编码获取库存
	 */
	async getInventoryByCode(itemCode) {
		try {
			if (!itemCode) {
				return formatResponse(400, null, '物品编码不能为空');
			}

			const res = await db.collection('dh-inventory')
				.where({ item_code: itemCode })
				.get();
			
			if (res.data.length === 0) {
				return formatResponse(404, null, '库存物品不存在');
			}
			return formatResponse(200, res.data[0]);
		} catch (error) {
			return formatError(error, '获取库存物品失败');
		}
	},

	/**
	 * 扫码获取库存信息（支持二维码和条形码）
	 */
	async getInventoryByScan(scanCode, scanType = 'qrcode') {
		try {
			if (!scanCode) {
				return formatResponse(400, null, '扫码内容不能为空');
			}

			let query = {};
			if (scanType === 'qrcode') {
				// 二维码可能包含JSON数据，尝试解析
				try {
					const qrcodeData = JSON.parse(scanCode);
					if (qrcodeData.item_code) {
						query.item_code = qrcodeData.item_code;
					}
				} catch (e) {
					// 如果不是JSON，直接当作二维码内容
					query.qrcode = scanCode;
				}
			} else if (scanType === 'barcode') {
				query.barcode = scanCode;
			} else {
				return formatResponse(400, null, '不支持的扫码类型');
			}

			const res = await db.collection('dh-inventory').where(query).get();
			
			if (res.data.length === 0) {
				return formatResponse(404, null, '未找到对应的库存物品');
			}
			return formatResponse(200, res.data[0]);
		} catch (error) {
			return formatError(error, '扫码获取库存失败');
		}
	},

	/**
	 * 获取库存列表
	 */
	async listInventory(query = {}, skip = 0, limit = 20) {
		try {
			if (typeof query !== 'object' || query === null || Array.isArray(query)) {
				query = {};
			}
			skip = parseInt(skip) || 0;
			limit = parseInt(limit) || 20;

			// 默认不显示已删除记录
			query.is_deleted = false;

			const res = await db.collection('dh-inventory')
				.where(query)
				.skip(skip)
				.limit(limit)
				.orderBy('create_time', 'desc')
				.get();

			// 检查库存状态并标记预警
			const dataWithStatus = res.data.map(item => {
				let autoStatus = item.status;
				if (item.current_quantity === 0) {
					autoStatus = 3; // 缺货
				} else if (item.current_quantity <= item.min_quantity) {
					autoStatus = 2; // 预警
				}
				return { ...item, auto_status: autoStatus };
			});

			return formatResponse(200, dataWithStatus, 'success', { count: dataWithStatus.length });
		} catch (error) {
			return formatError(error, '获取库存列表失败');
		}
	},

	/**
	 * 创建库存物品
	 */
	async createInventory(data) {
		try {
			const uniIdToken = this.getUniIdToken();
		if (!data.item_code || !data.item_name) {
			return formatResponse(400, null, '物品编码和物品名称不能为空');
		}

		// 检查物品编码是否已存在
		const existRes = await db.collection('dh-inventory')
			.where({ item_code: data.item_code })
			.count();
		
		if (existRes.total > 0) {
			return formatResponse(400, null, '物品编码已存在');
		}

		let inventoryData = {
				item_code: data.item_code,
				item_name: data.item_name,
				item_type: data.item_type || 4, // 默认为其他类型
				qrcode: data.qrcode || '',
				barcode: data.barcode || '',
				current_quantity: data.current_quantity || 0,
				min_quantity: data.min_quantity || 0,
				max_quantity: data.max_quantity || 0,
				unit_price: data.unit_price || 0,
				unit: data.unit || '',
				supplier: data.supplier || '',
				storage_location: data.storage_location || '',
				expiry_date: data.expiry_date || null,
				batch_no: data.batch_no || '',
				status: data.status || 1,
			is_controlled: data.is_controlled || false,
			is_deleted: false,  // 软删除字段，默认未删除
			create_time: Date.now(),
			update_time: Date.now()
		};

		// 🏥 自动挂载医院ID（单一医院系统特性）
		inventoryData = await autoMountHospitalId(inventoryData);

		const res = await db.collection('dh-inventory').add(inventoryData);
			
		// 记录库存变动日志（初始创建）
		await this._createInventoryLog({
			hospital_id: inventoryData.hospital_id,
				inventory_id: { _id: res.id, item_name: data.item_name, item_code: data.item_code },
				operation_type: 1, // 入库
				quantity: inventoryData.current_quantity,
				quantity_before: 0,
				quantity_after: inventoryData.current_quantity,
				operator_id: uniIdToken.uid,
				operator_name: uniIdToken.username || 'unknown',
				reason: '初始创建库存',
				scan_method: 'manual'
			});

			return formatResponse(201, { _id: res.id }, '库存物品创建成功');
		} catch (error) {
			return formatError(error, '创建库存物品失败');
		}
	},

	/**
	 * 更新库存物品信息
	 */
	async updateInventory(id, data) {
		try {
			if (!id) {
				return formatResponse(400, null, '库存ID不能为空');
			}

			const updateData = {
				...data,
				update_time: Date.now()
			};

			// 不允许直接修改库存数量，需要通过调整接口
			delete updateData.current_quantity;

			await db.collection('dh-inventory').doc(id).update(updateData);
			return formatResponse(200, null, '库存物品更新成功');
		} catch (error) {
			return formatError(error, '更新库存物品失败');
		}
	},

	/**
	 * 调整库存数量
	 */
	async adjustInventoryQuantity(id, quantity, operationType, reason = '', scanMethod = 'manual', department = '') {
		try {
			const uniIdToken = this.getUniIdToken();
			if (!id) {
				return formatResponse(400, null, '库存ID不能为空');
			}

			// 获取当前库存信息
			const currentRes = await db.collection('dh-inventory').doc(id).get();
			if (currentRes.data.length === 0) {
				return formatResponse(404, null, '库存物品不存在');
			}

			const currentItem = currentRes.data[0];
			const quantityBefore = currentItem.current_quantity;
			const quantityAfter = quantityBefore + quantity;

			if (quantityAfter < 0) {
				return formatResponse(400, null, '库存数量不足');
			}

			// 更新库存数量
			await db.collection('dh-inventory').doc(id).update({
				current_quantity: quantityAfter,
				update_time: Date.now()
			});

			// 根据新库存量自动更新状态
			let newStatus = 1; // 正常
			if (quantityAfter === 0) {
				newStatus = 3; // 缺货
			} else if (quantityAfter <= currentItem.min_quantity) {
				newStatus = 2; // 预警
			}
			await db.collection('dh-inventory').doc(id).update({ status: newStatus });

			// 记录库存变动日志
			await this._createInventoryLog({
				hospital_id: currentItem.hospital_id,
				inventory_id: { _id: id, item_name: currentItem.item_name, item_code: currentItem.item_code },
				operation_type: operationType,
				quantity: quantity,
				quantity_before: quantityBefore,
				quantity_after: quantityAfter,
				operator_id: uniIdToken.uid,
				operator_name: uniIdToken.username || 'unknown',
				department: department,
				reason: reason,
				scan_method: scanMethod
			});

			return formatResponse(200, { 
				quantity_before: quantityBefore, 
				quantity_after: quantityAfter 
			}, '库存数量调整成功');
		} catch (error) {
			return formatError(error, '调整库存数量失败');
		}
	},

	/**
	 * 删除库存物品
	 */
	async deleteInventory(id, reason = '') {
		try {
			if (!id) {
				return formatResponse(400, null, '库存ID不能为空');
			}

			const uniIdToken = this.getUniIdToken();
			const result = await softDelete('dh-inventory', id, uniIdToken?.uid || '', reason);
			
			if (result.code === 200) {
				return formatResponse(200, null, '库存物品已移至回收站');
			} else {
				return formatResponse(result.code, null, result.message);
			}
		} catch (error) {
			return formatError(error, '删除库存物品失败');
		}
	},

	/**
	 * 批量删除库存物品
	 */
	async batchDeleteInventory(ids, reason = '') {
		try {
			if (!Array.isArray(ids) || ids.length === 0) {
				return formatResponse(400, null, 'ID列表不能为空');
			}

			const uniIdToken = this.getUniIdToken();
			const result = await batchSoftDelete('dh-inventory', ids, uniIdToken?.uid || '', reason);
			
			return formatResponse(result.code, result.data, result.message);
		} catch (error) {
			return formatError(error, '批量删除失败');
		}
	},

	/**
	 * 获取库存预警列表
	 */
	async getInventoryAlerts(hospitalId) {
		try {
			if (!hospitalId) {
				return formatResponse(400, null, '医院ID不能为空');
			}

			// 查询缺货或预警状态的库存
			const res = await db.collection('dh-inventory')
				.where({
					'hospital_id._id': hospitalId,
					status: _.in([2, 3]) // 2-预警，3-缺货
				})
				.orderBy('status', 'desc') // 缺货优先
				.orderBy('current_quantity', 'asc') // 数量少的优先
				.get();

			return formatResponse(200, res.data, 'success', { count: res.data.length });
		} catch (error) {
			return formatError(error, '获取库存预警列表失败');
		}
	},

	/**
	 * 获取即将过期的库存
	 */
	async getExpiringInventory(hospitalId, daysBeforeExpiry = 30) {
		try {
			if (!hospitalId) {
				return formatResponse(400, null, '医院ID不能为空');
			}

			const now = Date.now();
			const expiryThreshold = now + (daysBeforeExpiry * 24 * 60 * 60 * 1000);

			const res = await db.collection('dh-inventory')
				.where({
					'hospital_id._id': hospitalId,
					expiry_date: _.and(_.gt(now), _.lt(expiryThreshold))
				})
				.orderBy('expiry_date', 'asc')
				.get();

			return formatResponse(200, res.data, 'success', { count: res.data.length });
		} catch (error) {
			return formatError(error, '获取即将过期库存失败');
		}
	},

	/**
	 * 获取库存变动日志
	 */
	async getInventoryLogs(inventoryId, skip = 0, limit = 20) {
		try {
			if (!inventoryId) {
				return formatResponse(400, null, '库存ID不能为空');
			}

			skip = parseInt(skip) || 0;
			limit = parseInt(limit) || 20;

			const res = await db.collection('dh-inventory_logs')
				.where({ 'inventory_id._id': inventoryId })
				.skip(skip)
				.limit(limit)
				.orderBy('create_time', 'desc')
				.get();

			return formatResponse(200, res.data, 'success', { count: res.data.length });
		} catch (error) {
			return formatError(error, '获取库存变动日志失败');
		}
	},

	/**
	 * 内部方法：创建库存变动日志
	 */
	async _createInventoryLog(logData) {
		try {
			const log = {
				hospital_id: logData.hospital_id,
				inventory_id: logData.inventory_id,
				operation_type: logData.operation_type,
				quantity: logData.quantity,
				quantity_before: logData.quantity_before,
				quantity_after: logData.quantity_after,
				operator_id: logData.operator_id,
				operator_name: logData.operator_name || '',
				department: logData.department || '',
				reason: logData.reason || '',
				related_order_id: logData.related_order_id || '',
				related_order_type: logData.related_order_type || '',
				scan_method: logData.scan_method || 'manual',
				create_time: Date.now()
			};

			await db.collection('dh-inventory_logs').add(log);
			console.log('[dh-inventory] 库存变动日志创建成功');
		} catch (error) {
			console.error('[dh-inventory] 创建库存变动日志失败:', error);
		}
	}
};

